﻿#ifndef CUSTOM_IBL_INCLUDED
#define CUSTOM_IBL_INCLUDED

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/EntityLighting.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/ImageBasedLighting.hlsl"

CBUFFER_START(_CustomIBL)
	float _iBLDiffuseScale;
	float _specularScale;

	//float _IrradianceScale;
	//float _SpecularReflectScale;

	half4 _iBLSpecularHDR_HDR;
CBUFFER_END


TEXTURECUBE(_iBLDiffuseHDR);
SAMPLER(sampler_iBLDiffuseHDR);

TEXTURECUBE(_iBLSpecularHDR);
SAMPLER(sampler_iBLSpecularHDR);


TEXTURE2D(_iBLBrdfLut);
SAMPLER(sampler_iBLBrdfLut);

struct IBL {
	float3 diffuse;
	float3 specular;
};

//float3 SampleLightMap (float2 lightMapUV) {
//	#if defined(LIGHTMAP_ON)
//  		return SampleSingleLightmap(
//			TEXTURE2D_ARGS(unity_Lightmap, samplerunity_Lightmap), lightMapUV,
//			float4(1.0, 1.0, 0.0, 0.0),
//			#if defined(UNITY_LIGHTMAP_FULL_HDR)
//				false,
//			#else
//				true,
//			#endif
//			float4(LIGHTMAP_HDR_MULTIPLIER, LIGHTMAP_HDR_EXPONENT, 0.0, 0.0)
//	);
//	#else
//		return 0.0;
//	#endif
//}
//
//float3 SampleLightProbe (Surface surfaceWS) {
//	#if defined(LIGHTMAP_ON)
//		return 0.0;
//	#else
//		if (unity_ProbeVolumeParams.x) {
//			return SampleProbeVolumeSH4(
//				TEXTURE3D_ARGS(unity_ProbeVolumeSH, samplerunity_ProbeVolumeSH),
//				surfaceWS.position, surfaceWS.normal,
//				unity_ProbeVolumeWorldToObject,
//				unity_ProbeVolumeParams.y, unity_ProbeVolumeParams.z,
//				unity_ProbeVolumeMin.xyz, unity_ProbeVolumeSizeInv.xyz
//			);
//		}
//		else {
//			float4 coefficients[7];
//			coefficients[0] = unity_SHAr;
//			coefficients[1] = unity_SHAg;
//			coefficients[2] = unity_SHAb;
//			coefficients[3] = unity_SHBr;
//			coefficients[4] = unity_SHBg;
//			coefficients[5] = unity_SHBb;
//			coefficients[6] = unity_SHC;
//			return max(0.0, SampleSH9(coefficients, surfaceWS.normal));
//		}
//	#endif
//}
//
//float4 SampleLightProbeOcclusion (Surface surfaceWS) {
//	return unity_ProbesOcclusion;
//}
//
//
//float4 SampleBakedShadows (float2 lightMapUV, Surface surfaceWS) {
//	#if defined(LIGHTMAP_ON)
//		return SAMPLE_TEXTURE2D(
//			unity_ShadowMask, samplerunity_ShadowMask, lightMapUV
//		);
//	#else
//		if (unity_ProbeVolumeParams.x) {
//			return SampleProbeOcclusion(
//				TEXTURE3D_ARGS(unity_ProbeVolumeSH, samplerunity_ProbeVolumeSH),
//				surfaceWS.position, unity_ProbeVolumeWorldToObject,
//				unity_ProbeVolumeParams.y, unity_ProbeVolumeParams.z,
//				unity_ProbeVolumeMin.xyz, unity_ProbeVolumeSizeInv.xyz
//			);
//		}
//		else {
//			return unity_ProbesOcclusion;
//		}
//	#endif
//}
//
//float3 SampleEnvironment (Surface surfaceWS, BRDF brdf) {
//	float3 uvw = reflect(-surfaceWS.viewDirection, surfaceWS.normal);
//	float mip = PerceptualRoughnessToMipmapLevel(brdf.perceptualRoughness);
//	float4 environment = SAMPLE_TEXTURECUBE_LOD(
//		unity_SpecCube0, samplerunity_SpecCube0, uvw, mip
//	);
//	return DecodeHDREnvironment(environment, unity_SpecCube0_HDR);
//}

#if defined(_IBL)&&defined(_IBL_RP_ON)
IBL GetIBL (Surface surface, BRDF brdf) {

	IBL ibl;	
	// 粗糙度
	// 将其重新映射到感知线性范围(perceptualRoughness*perceptualRoughness)
	float roughness = max(PerceptualRoughnessToRoughness(brdf.roughness), 0.002);
	half NdotV = abs(dot(surface.normal, surface.viewDirection)); // This abs allow to limit artifact	

	float3 F0 = brdf.specular;// lerp(0.04, albedo, metallic);
	//float3 F0 = lerp(0.04, surface.color, surface.metallic);

	float3 ks_indirect = FresnelSchlickRoughness(NdotV, F0, roughness);

	float3 kd_indirect = 1.0 - ks_indirect;
	kd_indirect *= (1 - surface.metallic);
	
	//float3 irradiance = texCUBE(_IrradianceCubemap, N).rgb;
	float3 irradiance = SAMPLE_TEXTURECUBE(_iBLDiffuseHDR, sampler_iBLDiffuseHDR, surface.normal).rgb;
	ibl.diffuse = kd_indirect * irradiance* surface.color * _iBLDiffuseScale * surface.irradianceScale;

	// 1.Li*NdotL
	// 预过滤环境贴图方式
	float3 R = reflect(-surface.viewDirection, surface.normal);

	// 根据粗糙度计算mip level
	half mip = PerceptualRoughnessToMipmapLevel(brdf.perceptualRoughness);
	float3 prefilteredColor = 0;
	// 自定义反射求需要把Cube Map贴图的 Mapping Convolution Type选项选为Specular(Glossy Reflection)
	half4 rgbm = SAMPLE_TEXTURECUBE_LOD(_iBLSpecularHDR, sampler_iBLSpecularHDR, R, mip);
	prefilteredColor = DecodeHDREnvironment(rgbm, _iBLSpecularHDR_HDR);

	//TEXTURECUBE(_iBLSpecularHDR);
	//SAMPLER(sampler_iBLSpecularHDR);
	//	float mip = PerceptualRoughnessToMipmapLevel(brdf.perceptualRoughness);
	//float4 environment = SAMPLE_TEXTURECUBE_LOD(
	//	unity_SpecCube0, samplerunity_SpecCube0, uvw, mip
	//);
	//return DecodeHDREnvironment(environment, unity_SpecCube0_HDR);
	// 最后结合两部分	
	//float2 envBRDF = tex2D(_BRDFLUTTex, float2(NdotV, roughness)).rg;
	//TEXTURE2D(_iBLBrdfLut);
	//SAMPLER(sampler_iBLBrdfLut);
	float2 envBRDF = SAMPLE_TEXTURE2D(_iBLBrdfLut, sampler_iBLBrdfLut, float2(NdotV, roughness)).rg;
	ibl.specular = prefilteredColor * (ks_indirect * envBRDF.x + envBRDF.y)* _specularScale* surface.specularReflectScale;

	return ibl;

}
#endif

#endif